package com.heima.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dtos.LoginDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.service.ApUserService;
import com.heima.utils.common.AppJwtUtil;
import com.heima.utils.common.MD5Utils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Service
public class  ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {
    /**
     * 这个便是登录功能的处理逻辑
     * 对前端传来的dto（手机和密码）两个数据，去数据库查
     * 密码先加salt 再进行md5加密
     * 同时还会有游客登录（没有账号密码）和用户登录（有账号密码）
     *
     * @param loginDto
     * @return
     */
    @Override
    public ResponseResult login(LoginDto loginDto) {
        //1.游客登录
        try {
            if (StringUtils.isEmpty(loginDto.getPhone()) && StringUtils.isEmpty(loginDto.getPassword())) {
                //游客登录的业务逻辑,只是传一个token就可以，也用map来存
                Map<String, Object> map = new HashMap<>();
                String token = AppJwtUtil.getToken(0L);
                map.put("token", token);
                return ResponseResult.okResult(map);
            }
        } catch (Exception e) {
            //printStackTrace()方法的作用就是打印出异常的位置
            e.printStackTrace();
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }

        //2.用户登录
        LambdaQueryWrapper<ApUser> loginWrapper = new LambdaQueryWrapper<>();
        loginWrapper.eq(loginDto.getPhone() != null, ApUser::getPhone, loginDto.getPhone());

        ApUser apUser = null;
        try {
            apUser = this.getOne(loginWrapper);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }

        if (apUser == null) {
            //数据库查不到这个手机号则没有注册过
            return ResponseResult.errorResult(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST, "用户不存在，请先完成注册！");
        }
        //查到了用户，说明注册了，所以对其密码进行验证，把dto的password先加salt再Md5
        String salt = apUser.getSalt();
        String password = loginDto.getPassword() + salt;
        String psw = DigestUtils.md5DigestAsHex(password.getBytes());
        //加盐加密完成后对比密码，命中符合则登录成功，不符合则登录失败
        if (apUser.getPassword().equals(psw) != true) {
            return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR, "密码错误！");
        }
        //正常登录成功，返回jwt（jason web token）
        String token = AppJwtUtil.getToken((long) apUser.getId());
        //传给前端的数据是一个json对象，包含了 user的信息和token ，咱们用一个map来存储
        Map<String, Object> map = new HashMap<>();
        /*
         * 为了安全起见，返回给前端的数据不会带上盐和密码，在这里我手动置位空
         * */
        apUser.setPassword("");
        apUser.setSalt("");
        map.put("data", apUser);
        map.put("token", token);
        return ResponseResult.okResult(map);

    }
}
